package dao;

import java.sql.Connection;  
import java.sql.ResultSet;  
import java.sql.SQLException;  
import java.sql.Statement;  
import java.util.Vector;  
import javax.swing.JOptionPane;  
import modelo.dominio.Veiculo;
import dao.banco.ConFactory;  
import modelo.dominio.Locacao;
import modelo.dominio.TipoVeiculo;
import visaoInterface.VeiculosMaisRentaveis;
  
public class DaoVeiculo {  
   
   private final String URL = "jdbc:mysql://localhost/bd_locarrao",  
         NOME = "root", SENHA = "locarrao2";  
   private Connection con;  
   private Statement comando;  
   
   public boolean tabelaBDehVazia(){
      conectar();  
      Vector<Veiculo> resultados = new Vector<Veiculo>();  
      ResultSet rs;  
      try {  
         rs = comando.executeQuery("SELECT * FROM tb_veiculo");  
         while (rs.next()) {  
            Veiculo temp = new Veiculo();
            temp.setPlaca(rs.getString("placa"));  
            temp.setMarca(rs.getString("marca"));  
            temp.setModelo(rs.getString("modelo"));
            temp.setCor(rs.getString("cor"));
            resultados.add(temp);  
            break;
         }  
         
      } catch (SQLException e) {  
         imprimeErro("Erro ao buscar veiculos.", e.getMessage());  
      }
      return (resultados.isEmpty());
   }
  
   public void apagar(String placa) {  
      conectar();  
      try {  
         comando.executeUpdate("DELETE FROM veiculo WHERE placa = '" + placa  
                     + "';");  
      } catch (SQLException e) {  
         imprimeErro("Erro ao apagar o veiculo", e.getMessage());  
      } finally {  
         fechar();  
      }  
   }  
  
   public Vector<Veiculo> buscarTodos() {  
      conectar();  
      Vector<Veiculo> resultados = new Vector<Veiculo>();  
      ResultSet rs;  
      try {  
         rs = comando.executeQuery("SELECT * FROM tb_veiculo");  
         while (rs.next()) {  
            Veiculo temp = new Veiculo();
            temp.setCodTipoVeiculo(rs.getInt("cod_tipo_veic"));
            temp.setCodTipoVeiculo(rs.getInt("cod_veiculo"));
            temp.setPlaca(rs.getString("placa"));  
            temp.setMarca(rs.getString("marca"));  
            temp.setModelo(rs.getString("modelo"));
            temp.setCor(rs.getString("cor"));
            resultados.add(temp);  
         }  
         return resultados;  
      } catch (SQLException e) {  
         imprimeErro("Erro ao buscar veiculos.", e.getMessage());  
         return null;  
      }  
   }
  
   public void atualizar(Veiculo veiculo) {  
      conectar();  
      String com = "UPDATE tb_veiculo SET num_loc = '" + veiculo.getNumeroLocacoes() + "', disponivel = '0' WHERE cod_veiculo = '" + veiculo.getCodVeiculo() + "';";
      System.out.println("Atualizada!");
      
      try {  
         comando.executeUpdate(com);  
      } catch (SQLException e) {  
         e.printStackTrace();  
      } finally {  
         fechar();  
      }  
   }
      public void atualizarVeiculoPorLocacao(Locacao locacao,Veiculo veiculo) {  
      conectar();
      String com = "UPDATE tb_veiculo SET soma_loc = '" + veiculo.getSomaLocacoes() + "', km_atual = '" + veiculo.getKmAtual() + "' WHERE cod_veiculo = '" + locacao.getCodVeiculo() + "';";
      System.out.println("Atualizada!");
      
      try {  
         comando.executeUpdate(com);  
      } catch (SQLException e) {  
         e.printStackTrace();  
      } finally {  
         fechar();  
      }  
   } 
   
   /**
    * Método que busca no banco de dados o numero de locações em cada veiculo para saber
    * qual é o mais procurado. Feito isso ele guarda os objetos veiculos
    * com os dados em um vetor de veiculos.
    * @return um vetor de veiculos para exibir na tabela.
    * @see VeiculosMaisProcurados
    */
   
   public Vector<Veiculo> buscarMaisProcurados(){
       conectar();
       ResultSet rs;
       Vector<Veiculo> maisProcurados = new Vector<Veiculo>();
        try { 
         // busca ordenado de forma decrecente no banco de dados
         rs = comando.executeQuery("SELECT * FROM tb_veiculo ORDER BY `num_loc` DESC");
         while (rs.next()) {  
            Veiculo temp = new Veiculo();
            temp.setNumeroLocacoes(Integer.parseInt(rs.getString("num_loc")));
            temp.setPlaca(rs.getString("placa"));  
            temp.setMarca(rs.getString("marca"));  
            temp.setModelo(rs.getString("modelo"));
            temp.setCor(rs.getString("cor"));
            maisProcurados.add(temp);  
         }  
         return maisProcurados;  
      } catch (SQLException e) {  
         imprimeErro("Erro ao buscar o veiculo.", e.getMessage());  
         return null;  
      }  
       
   }
   
   /**
    * Método que busca no bando de dados o soma locações de cada veiculo, para
    * saber qual é o mais rentavel. Feito isso ele guarda os objetos veiculos
    * com os dados em um vetor veiculo.
    * @return um vetor de veiculos ordenado para exibir na tabela
    * @see VeiculosMaisRentaveis
    */
   public Vector<Veiculo> buscarMaisRentaveis(){
       conectar();
       ResultSet rs;
       Vector<Veiculo> maisProcurados = new Vector<Veiculo>();
        try { 
         // busca ordenado de forma decrecente no banco de dados
         rs = comando.executeQuery("SELECT * FROM tb_veiculo ORDER BY `soma_loc` DESC");
         while (rs.next()) {  
            Veiculo temp = new Veiculo();
            temp.setSomaLocacoes(Double.parseDouble(rs.getString("soma_loc")));
            temp.setPlaca(rs.getString("placa"));  
            temp.setMarca(rs.getString("marca"));  
            temp.setModelo(rs.getString("modelo"));
            temp.setCor(rs.getString("cor"));
            maisProcurados.add(temp);  
         }  
         return maisProcurados;  
      } catch (SQLException e) {  
         imprimeErro("Erro ao buscar o veiculo.", e.getMessage());  
         return null;  
      }  
       
   }
   
   /**
    * Busca no banco de dados pela placa do veiculo
    * @param placa parametro para a pesquisa, para busca pela placa
    * @return vetor de veiculos.
    */
   public Vector<Veiculo> buscar(String placa) {  
      conectar();  
      Vector<Veiculo> resultados = new Vector<Veiculo>();  
      ResultSet rs;  
      try {  
         rs = comando.executeQuery("SELECT * FROM tb_veiculo WHERE placa LIKE '"  
               + placa + "%';");  
         while (rs.next()) {  
            Veiculo temp = new Veiculo();   
            temp.setPlaca(rs.getString("placa"));  
            temp.setMarca(rs.getString("marca"));  
            temp.setModelo(rs.getString("modelo"));
            temp.setCor(rs.getString("cor"));
            resultados.add(temp);  
         }  
         return resultados;  
      } catch (SQLException e) {  
         imprimeErro("Erro ao buscar o veiculo.", e.getMessage());  
         return null;  
      }  
  
   }
   
    /**
    * Método que pega o codigo digitado pelo usuario e retorna  do banco de dados 
    * o obejto veiculo
    * @param cod codigo do veiculo
    * @return o obejto veiculo
    */ 
   public Veiculo buscarObjetoPorCod(int cod) {  
      conectar();  
      Veiculo temp = new Veiculo();  
      ResultSet rs;  
      try {  
         rs = comando.executeQuery("SELECT * FROM tb_veiculo WHERE cod_veiculo LIKE '"  
               + cod + "%';");
         while (rs.next()) {  
            temp.setCodVeiculo(rs.getInt("cod_veiculo"));
            temp.setPlaca(rs.getString("placa"));  
            temp.setMarca(rs.getString("marca"));  
            temp.setModelo(rs.getString("modelo"));
            temp.setCor(rs.getString("cor"));
            temp.setNumeroLocacoes(rs.getInt("num_loc"));
            temp.setCodTipoVeiculo(rs.getInt("cod_tipo_veic"));
            temp.setSomaLocacoes(rs.getDouble("soma_loc"));
            temp.setKmAtual(rs.getDouble("km_atual"));
            
         }
         return temp;  
      } catch (SQLException e) {  
         imprimeErro("Erro ao buscar o veiculo.", e.getMessage());  
         return null;  
      }  
  
   }
   
    /**
    *Método que busca no banco de dados um veiculo pelo modelo que o usuario digita 
    * @param modelo
    * @return 
    */ 
      public Vector<Veiculo> buscarVeiculoPorNome(String modelo) {  
      conectar();  
      Vector<Veiculo> resultados = new Vector<Veiculo>();  
      ResultSet rs;  
      try {  
         rs = comando.executeQuery("SELECT * FROM tb_veiculo WHERE modelo LIKE '"  
               + modelo + "%';");
         while (rs.next()) {  
            Veiculo temp = new Veiculo();
            temp.setCodTipoVeiculo(rs.getInt("cod_tipo_veic"));
            temp.setCodVeiculo(rs.getInt("cod_veiculo"));
            temp.setPlaca(rs.getString("placa"));  
            temp.setMarca(rs.getString("marca"));  
            temp.setModelo(rs.getString("modelo"));
            temp.setCor(rs.getString("cor"));
            resultados.add(temp);
         }
         return resultados;  
      } catch (SQLException e) {  
         imprimeErro("Erro ao buscar o veiculo.", e.getMessage());  
         return null;  
      }  
  
   }
      /**
       * Método que busca os veiculos por modelo e adiciona no vetor de retorno
       * só os que possuem disponibilidade igual a um
       * @param modelo  modelo dos veiculos que quer procurar
       * @return vector de veiculos disponiveis
       */
      public Vector<Veiculo> buscarVeiculoDisponiveisPorNome(String modelo) {  
      conectar();  
      Vector<Veiculo> resultados = new Vector<Veiculo>();  
      ResultSet rs;  
      try {  
         rs = comando.executeQuery("SELECT * FROM tb_veiculo WHERE modelo LIKE '"  
               + modelo + "%';");
         while (rs.next()) {  
            Veiculo temp = new Veiculo();
            temp.setCodTipoVeiculo(rs.getInt("cod_tipo_veic"));
            temp.setCodVeiculo(rs.getInt("cod_veiculo"));
            temp.setPlaca(rs.getString("placa"));  
            temp.setMarca(rs.getString("marca"));  
            temp.setModelo(rs.getString("modelo"));
            temp.setCor(rs.getString("cor"));
            if (rs.getInt("disponivel")==1){
                resultados.add(temp); 
                }
         }
         return resultados;  
      } catch (SQLException e) {  
         imprimeErro("Erro ao buscar o veiculo.", e.getMessage());  
         return null;  
      }  
  
   }   
       
      /**
       * Método que busca os veiculos disponiveis no banco de dados, que sao
       * igual a um para pesquisa.
       * @return vetor de veiculos disponiveis para mostrar na tabela.
       */   
        public Vector<Veiculo> buscarVeiculosDisponiveis() { 
        conectar();  
       Vector<Veiculo> resultados = new Vector<Veiculo>();  
       ResultSet rs;
       int disponivel = 1;
       try {  
         rs = comando.executeQuery("SELECT * FROM tb_veiculo WHERE disponivel LIKE '" +disponivel+ "%';");
        while (rs.next()) {   
            Veiculo temp = new Veiculo();  
            temp.setCodTipoVeiculo(rs.getInt("cod_tipo_veic"));
            temp.setCodVeiculo(rs.getInt("cod_veiculo"));
            temp.setPlaca(rs.getString("placa"));  
            temp.setMarca(rs.getString("marca"));  
            temp.setModelo(rs.getString("modelo"));
            temp.setCor(rs.getString("cor"));
                if (rs.getInt("disponivel")==1){
                 resultados.add(temp); 
          }
        }   
        return resultados;  
      } catch (SQLException e) {  
         imprimeErro("Erro ao buscar pessoa", e.getMessage());  
         return null;  
      }  
   }
      
      /**
       * Método que faz a busca do codigo do tipo veiculo no banco de dados, para
       * saber qual tipo veiculo pertence a tal veiculo, para ter os dados do seu
       * tipo de veiculo
       * @param tipo String do tipo veiculo contido no veiculo que deseja ter os dados.
       * @return codigo do tipo veiculo referente ao veiculo.
       */
      public int buscarCodTipoVeiculo(String tipo){
          conectar();
          int cod = 0;
          ResultSet rs;
          
          try{
           rs = comando.executeQuery("SELECT cod_tipo_veic FROM tb_tipo_veiculo WHERE tipo = '"+tipo+"';");
               
              while (rs.next()){
                  
                  cod = rs.getInt("cod_tipo_veic");
                   
              } 
              
              
            return cod;
          }catch (SQLException e) {  
         imprimeErro("Erro ao buscar veiculos.", e.getMessage());  
         return 0;
        }
      } 
      
      /**
       * Método que busca no banco de dados o codigo digitado pelo usuario do
       * tipo de veiculo e retorna os veiculos desse determinado tipo
       * @param cod o codigo do tipo veiculo
       * @return um vetor de veiculos de determinado tipo
       */
      public Vector<Veiculo> buscarVeiculosDeDeterminadoTipo(int cod){
      conectar();  
      Vector<Veiculo> resultados = new Vector<Veiculo>();  
      ResultSet  rs;
      try {
            
 
            rs = comando.executeQuery("SELECT * FROM tb_veiculo WHERE cod_tipo_veic = '"  + cod + "%';");
            while (rs.next()) {

                Veiculo temp = new Veiculo();  
                temp.setCodTipoVeiculo(rs.getInt("cod_tipo_veic"));
                temp.setCodVeiculo(rs.getInt("cod_veiculo"));
                temp.setPlaca(rs.getString("placa"));  
                temp.setMarca(rs.getString("marca"));  
                temp.setModelo(rs.getString("modelo"));
                temp.setCor(rs.getString("cor"));
                if (rs.getInt("disponivel")==1){
                resultados.add(temp); 
                } 
                  
            }  
            
         return resultados;  
      } catch (SQLException e) {  
         imprimeErro("Erro ao buscar veiculos.", e.getMessage());  
         return null;  
      }
      }
      
      /**
       * Insere no banco de dados um veiculo.
       * @param veiculo recebe o veiculo a ser adicionado no banco de dados
       * @param cod o codigo referente ao veiculo
       */
      public void insere(Veiculo veiculo, int cod){  
      conectar();
      int disponivel = 1;
      try {
         if (veiculo.isDisponivel()){
             disponivel = 1;
         }else{
             disponivel = 0;
         } 
         comando.executeUpdate("INSERT INTO `bd_locarrao`.`tb_veiculo` (`placa`,`marca`,`cor`,`modelo`,`km_atual`,`cod_tipo_veic`,`disponivel`) VALUES ('" + veiculo.getPlaca() + "','" + veiculo.getMarca() + "','" + veiculo.getCor() + "', '" + veiculo.getModelo() + "', '" + veiculo.getKmAtual() + "','"+cod+"','"+disponivel+"')");
         System.out.println("Inserida!");
      } catch (SQLException e) {  
         imprimeErro("Erro ao inserir Veiculo", e.getMessage());  
      } finally {  
         fechar();
      }  
   }  
   
      /**
       * Conecta com o banco de dados.
       */
   private void conectar() {  
      try {  
         con = ConFactory.conexao(URL, NOME, SENHA, ConFactory.MYSQL);  
         comando = con.createStatement();  
         System.out.println("Conectado!");  
      } catch (ClassNotFoundException e) {  
         imprimeErro("Erro ao carregar o driver", e.getMessage());  
      } catch (SQLException e) {  
         imprimeErro("Erro ao conectar", e.getMessage());  
      }  
   }  
   /**
    * Fecha o banco de dados.
    */
   private void fechar() {  
      try {  
         comando.close();  
         con.close();  
         System.out.println("Conexão Fechada");  
      } catch (SQLException e) {  
         imprimeErro("Erro ao fechar conexão", e.getMessage());  
      }  
   }  
  
   private void imprimeErro(String msg, String msgErro) {  
      JOptionPane.showMessageDialog(null, msg, "Erro crítico", 0);  
      System.err.println(msg);  
      System.out.println(msgErro);  
      System.exit(0);  
   }  
}  
